<script setup lang="ts">
import {
    Input as AInput,
    InputNumber as AInputNumber,
    Modal as AModal,
    Option as AOption,
    Select as ASelect
} from '@arco-design/web-vue'
import {computed, nextTick, onMounted, ref, toRaw, watch} from 'vue'

interface GradientPreset {
    name: string
    colors: string[]
    direction: string
    isCustom?: boolean
}

interface ColorStop {
    color: string
    position: number
}

// 预设渐变
const presets: GradientPreset[] = [
    {name: '日落', colors: ['#ff9a9e', '#fecfef', '#fecfef'], direction: 'to right', isCustom: false},
    {name: '海洋', colors: ['#667eea', '#764ba2'], direction: 'to right', isCustom: false},
    {name: '森林', colors: ['#11998e', '#38ef7d'], direction: 'to right', isCustom: false},
    {name: '紫色梦幻', colors: ['#667eea', '#764ba2'], direction: 'to bottom', isCustom: false},
    {name: '橙色活力', colors: ['#ffecd2', '#fcb69f'], direction: 'to right', isCustom: false},
    {name: '蓝色天空', colors: ['#667eea', '#764ba2'], direction: 'to top', isCustom: false},
]

// 当前渐变设置
const selectedPresetIndex = ref<number>(0)
const selectedSavedPresetIndex = ref<number | null>(null)
const customColors = ref<ColorStop[]>([
    {color: '#667eea', position: 0},
    {color: '#764ba2', position: 100}
])
const direction = ref('to right')
const exportWidth = ref(800)
const exportHeight = ref(600)

// 视频尺寸选项
const videoSizes = [
    {label: 'Full HD (横屏)', width: 1920, height: 1080},
    {label: 'HD (横屏)', width: 1280, height: 720},
    {label: '4K UHD (横屏)', width: 3840, height: 2160},
    {label: 'Full HD (竖屏)', width: 1080, height: 1920},
    {label: 'HD (竖屏)', width: 720, height: 1280},
    {label: '4K UHD (竖屏)', width: 2160, height: 3840},
]

const selectedVideoSize = ref<number | null>(null)
const canvasRef = ref<HTMLCanvasElement | null>(null)

// 计算CSS
const gradientCSS = computed(() => {
    const colors = customColors.value.map(stop => `${stop.color} ${stop.position}%`).join(', ')
    return `linear-gradient(${direction.value}, ${colors})`
})

// 应用视频尺寸
const applyVideoSize = (index: number) => {
    const size = videoSizes[index]
    exportWidth.value = size.width
    exportHeight.value = size.height
}

// 保存的预设
const savedPresetsArray = ref<GradientPreset[]>([])

// Modal状态
const saveModalVisible = ref(false)
const presetName = ref('')

// 计算保存的预设
const savedPresets = computed(() => savedPresetsArray.value)

// 计算保存的预设

// 保存设置
const saveSettings = async () => {
    const settings = {
        exportWidth: exportWidth.value,
        exportHeight: exportHeight.value,
        direction: direction.value,
        customColors: customColors.value
    }
    await focusany.dbStorage.setItem('bgImageSettings', toRaw(settings))
}

// 加载设置
const loadSettings = async () => {
    const settings = await focusany.dbStorage.getItem('bgImageSettings')
    if (settings) {
        exportWidth.value = settings.exportWidth || 800
        exportHeight.value = settings.exportHeight || 600
        direction.value = settings.direction || 'to right'
        customColors.value = settings.customColors || [
            {color: '#667eea', position: 0},
            {color: '#764ba2', position: 100}
        ]
        return true // 表示有保存的设置
    }
    return false // 没有保存的设置
}

// 应用预设
const applyPreset = (preset: GradientPreset) => {
    const index = presets.indexOf(preset)
    if (index !== -1) {
        selectedPresetIndex.value = index
    }
    customColors.value = preset.colors.map((color, index) => ({
        color,
        position: index === 0 ? 0 : index === preset.colors.length - 1 ? 100 : (index / (preset.colors.length - 1)) * 100
    }))
    direction.value = preset.direction
    drawCanvas()
}

// 处理预设选择
const handlePresetChange = (index: any) => {
    if (typeof index === 'number' && presets[index]) {
        applyPreset(presets[index])
    }
}

// 处理保存预设选择
const handleSavedPresetChange = (index: any) => {
    if (typeof index === 'number' && savedPresets.value[index]) {
        applyPreset(savedPresets.value[index])
    }
}

// 添加颜色
const addColor = () => {
    const newPosition = Math.floor(Math.random() * 90) + 5 // 随机位置5-95
    customColors.value.push({color: '#ffffff', position: newPosition})

    // 重新排序并调整位置
    customColors.value.sort((a, b) => a.position - b.position)
    customColors.value[0].position = 0
    customColors.value[customColors.value.length - 1].position = 100

    // 均匀分布其他颜色
    for (let i = 1; i < customColors.value.length - 1; i++) {
        customColors.value[i].position = Math.round((i / (customColors.value.length - 1)) * 100)
    }

    drawCanvas()
}

// 删除颜色
const removeColor = (index: number) => {
    if (customColors.value.length > 2) {
        customColors.value.splice(index, 1)
        drawCanvas()
    }
}

// 更新颜色
const updateColor = (index: number, color: string) => {
    customColors.value[index].color = color
    drawCanvas()
}

// 更新位置
const updatePosition = (index: number, position: number) => {
    customColors.value[index].position = position
    drawCanvas()
}

// 绘制Canvas
const drawCanvas = () => {
    if (!canvasRef.value) return

    const canvas = canvasRef.value
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    // 获取容器尺寸
    const container = canvas.parentElement?.parentElement
    if (container) {
        const containerWidth = container.clientWidth - 32 // 减去padding
        const containerHeight = Math.min(container.clientHeight - 32, 300) // 最大高度300px

        // 设置Canvas尺寸为容器尺寸
        canvas.width = Math.max(containerWidth, 200) // 最小宽度200px
        canvas.height = Math.max(containerHeight, 150) // 最小高度150px
    } else {
        // 默认尺寸
        canvas.width = 400
        canvas.height = 300
    }

    // 创建渐变
    let x0 = 0, y0 = 0, x1 = canvas.width, y1 = canvas.height
    if (direction.value === 'to right') {
        x0 = 0;
        y0 = 0;
        x1 = canvas.width;
        y1 = 0
    } else if (direction.value === 'to left') {
        x0 = canvas.width;
        y0 = 0;
        x1 = 0;
        y1 = 0
    } else if (direction.value === 'to bottom') {
        x0 = 0;
        y0 = 0;
        x1 = 0;
        y1 = canvas.height
    } else if (direction.value === 'to top') {
        x0 = 0;
        y0 = canvas.height;
        x1 = 0;
        y1 = 0
    } else if (direction.value === 'to bottom right') {
        x0 = 0;
        y0 = 0;
        x1 = canvas.width;
        y1 = canvas.height
    } else if (direction.value === 'to bottom left') {
        x0 = canvas.width;
        y0 = 0;
        x1 = 0;
        y1 = canvas.height
    } else if (direction.value === 'to top right') {
        x0 = 0;
        y0 = canvas.height;
        x1 = canvas.width;
        y1 = 0
    } else if (direction.value === 'to top left') {
        x0 = canvas.width;
        y0 = canvas.height;
        x1 = 0;
        y1 = 0
    }

    const gradient = ctx.createLinearGradient(x0, y0, x1, y1)

    customColors.value.forEach(stop => {
        gradient.addColorStop(stop.position / 100, stop.color)
    })

    // 填充渐变
    ctx.fillStyle = gradient
    ctx.fillRect(0, 0, canvas.width, canvas.height)
}

// 复制CSS
const copyCSS = async () => {
    try {
        await navigator.clipboard.writeText(gradientCSS.value)
        focusany.showNotification('CSS 已复制到剪贴板')
    } catch (error) {
        focusany.showNotification('复制失败')
    }
}

// 导出PNG
const exportPNG = () => {
    if (!canvasRef.value) return

    const canvas = canvasRef.value
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    // 设置Canvas尺寸
    canvas.width = exportWidth.value
    canvas.height = exportHeight.value

    // 创建渐变
    let x0 = 0, y0 = 0, x1 = canvas.width, y1 = canvas.height
    if (direction.value === 'to right') {
        x0 = 0;
        y0 = 0;
        x1 = canvas.width;
        y1 = 0
    } else if (direction.value === 'to left') {
        x0 = canvas.width;
        y0 = 0;
        x1 = 0;
        y1 = 0
    } else if (direction.value === 'to bottom') {
        x0 = 0;
        y0 = 0;
        x1 = 0;
        y1 = canvas.height
    } else if (direction.value === 'to top') {
        x0 = 0;
        y0 = canvas.height;
        x1 = 0;
        y1 = 0
    } else if (direction.value === 'to bottom right') {
        x0 = 0;
        y0 = 0;
        x1 = canvas.width;
        y1 = canvas.height
    } else if (direction.value === 'to bottom left') {
        x0 = canvas.width;
        y0 = 0;
        x1 = 0;
        y1 = canvas.height
    } else if (direction.value === 'to top right') {
        x0 = 0;
        y0 = canvas.height;
        x1 = canvas.width;
        y1 = 0
    } else if (direction.value === 'to top left') {
        x0 = canvas.width;
        y0 = canvas.height;
        x1 = 0;
        y1 = 0
    }

    const gradient = ctx.createLinearGradient(x0, y0, x1, y1)

    customColors.value.forEach(stop => {
        gradient.addColorStop(stop.position / 100, stop.color)
    })

    // 填充渐变
    ctx.fillStyle = gradient
    ctx.fillRect(0, 0, canvas.width, canvas.height)

    // 下载
    const link = document.createElement('a')
    link.download = 'gradient.png'
    link.href = canvas.toDataURL()
    link.click()
}

// 保存预设
const savePreset = async () => {
    presetName.value = ''
    saveModalVisible.value = true
}

// 确认保存预设
const confirmSavePreset = async () => {
    if (!presetName.value.trim()) {
        focusany.showNotification('请输入预设名称')
        return
    }

    const preset: GradientPreset = {
        name: presetName.value.trim(),
        colors: customColors.value.map(stop => stop.color),
        direction: direction.value,
        isCustom: true
    }

    const savedPresets = await focusany.dbStorage.getItem('gradientPresets') || []
    savedPresets.push(preset)
    await focusany.dbStorage.setItem('gradientPresets', toRaw(savedPresets))
    savedPresetsArray.value.push(preset)
    saveModalVisible.value = false
    focusany.showNotification('预设已保存')
}

// 删除保存的预设
const deleteSavedPreset = async (index: number) => {
    savedPresetsArray.value.splice(index, 1)
    const saved = await focusany.dbStorage.getItem('gradientPresets') || []
    saved.splice(index, 1)
    await focusany.dbStorage.setItem('gradientPresets', toRaw(saved))
    focusany.showNotification('预设已删除')
}

// 加载预设
const loadPresets = async () => {
    const saved = await focusany.dbStorage.getItem('gradientPresets') || []
    savedPresetsArray.value = saved.map((p: any) => ({...p, isCustom: true}))
}

onMounted(async () => {
    const hasSettings = await loadSettings()
    await loadPresets()
    if (!hasSettings && presets.length > 0) {
        applyPreset(presets[0]) // 只有在没有保存设置时才应用默认预设
    }
    drawCanvas()

    // 添加窗口大小变化监听
    const resizeObserver = new ResizeObserver(() => {
        drawCanvas()
    })

    // 监听canvas容器的大小变化
    const canvasContainer = canvasRef.value?.parentElement?.parentElement
    if (canvasContainer) {
        resizeObserver.observe(canvasContainer)
    }
})

// 监听设置变化并保存
watch([exportWidth, exportHeight, direction, customColors], () => {
    saveSettings()
}, {deep: true})

focusany.registerCallPage<{
    name: string,
    width: number,
    height: number
}, string>('GenerateGradientImage', async (resolve, reject, data) => {
    console.log('GenerateGradientImage', data)
    if (!data || !data.name || !data.width || !data.height) {
        return reject('参数错误');
    }
    await loadSettings()
    await loadPresets()
    exportWidth.value = data.width
    exportHeight.value = data.height
    presetName.value = data.name.trim()
    selectedSavedPresetIndex.value = null
    console.log('presetName', presetName.value)
    for (let i = 0; i < savedPresets.value.length; i++) {
        if (savedPresets.value[i].name === presetName.value) {
            selectedSavedPresetIndex.value = i
            applyPreset(savedPresets.value[i])
            break
        }
    }
    if (null === selectedSavedPresetIndex.value) {
        return reject('未找到对应预设');
    }
    nextTick(() => {
        const imageBase64 = canvasRef.value?.toDataURL() || ''
        console.log('imageBase64', imageBase64)
        if (!imageBase64) {
            return reject('生成图片失败');
        }
        return resolve(imageBase64)
    })
})

</script>

<template>
    <div class="h-screen flex bg-gray-100">
        <!-- 左侧预览区域 -->
        <div class="flex-1 flex flex-col min-h-0">
            <!-- 预览区域 -->
            <div class="flex-1 p-4 min-h-0">
                <div class="bg-white rounded-lg shadow-lg h-full flex items-center justify-center min-h-0">
                    <canvas ref="canvasRef" :style="{ background: gradientCSS }"
                            class="w-full h-full rounded-lg object-contain"></canvas>
                </div>
            </div>

            <!-- 底部颜色选择器 - 固定高度 -->
            <div class="flex-shrink-0 p-4 bg-white border-t shadow-lg">
                <div class="flex flex-wrap gap-2">
                    <div v-for="(stop, index) in customColors" :key="index" class="flex items-center gap-2">
                        <input type="color" :value="stop.color"
                               @input="updateColor(index, ($event.target as any).value)"
                               class="w-8 h-8 border rounded cursor-pointer"/>
                        <a-input-number v-model="stop.position" :min="0" :max="100" :step="1"
                                        @change="updatePosition(index, stop.position)" class="w-16" size="mini"/>
                        <button v-if="customColors.length > 2" @click="removeColor(index)"
                                class="text-red-500 hover:text-red-700 text-lg leading-none">
                            ×
                        </button>
                    </div>
                    <button @click="addColor"
                            class="px-3 py-1 bg-blue-500 text-white rounded text-sm hover:bg-blue-600">
                        添加颜色
                    </button>
                </div>
            </div>
        </div>

        <!-- 右侧工具栏 -->
        <div class="w-56 bg-white shadow-lg overflow-y-auto">
            <div class="p-4 space-y-4">
                <!-- 预设 -->
                <div class="pb-2">
                    <h3 class="font-semibold mb-3">预设</h3>
                    <a-select v-model="selectedPresetIndex" @change="handlePresetChange"
                              class="w-full border border-gray-300 rounded-md shadow-sm" placeholder="选择预设"
                              :dropdown-style="{ maxWidth: '100%', overflow: 'hidden' }">
                        <a-option v-for="(preset, index) in presets" :key="preset.name + index" :value="index"
                                  :style="{ width: '100%', overflow: 'hidden', padding: '0', display: 'block' }">
                            <div class="w-full" style="padding:1px 2px;">
                                <div
                                    :style="{ background: `linear-gradient(${preset.direction}, ${preset.colors.join(', ')})`, color: 'white', textShadow: '1px 1px 2px rgba(0,0,0,0.7)', border: '1px solid rgba(255,255,255,0.3)', borderRadius: '4px', padding: '4px 8px', width: '100%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }">
                                    {{ preset.name }}
                                </div>
                            </div>
                        </a-option>
                    </a-select>
                </div>

                <!-- 已保存的 -->
                <div class="pb-2">
                    <h3 class="font-semibold mb-3">已保存</h3>
                    <a-select v-model="selectedSavedPresetIndex as any" @change="handleSavedPresetChange"
                              class="w-full border border-gray-300 rounded-md shadow-sm" placeholder="选择已保存"
                              :dropdown-style="{ maxWidth: '100%', overflow: 'hidden' }">
                        <template #label>
                            {{
                                selectedSavedPresetIndex !== null ? savedPresets[selectedSavedPresetIndex]?.name :
                                    '选择已保存'
                            }}
                        </template>
                        <a-option v-for="(preset, index) in savedPresets" :key="preset.name + index" :value="index"
                                  :style="{ width: '100%', overflow: 'hidden', padding: '0', display: 'block' }">
                            <div class="w-full" style="padding:1px 2px;">
                                <div
                                    :style="{ background: `linear-gradient(${preset.direction}, ${preset.colors.join(', ')})`, color: 'white', textShadow: '1px 1px 2px rgba(0,0,0,0.7)', border: '1px solid rgba(255,255,255,0.3)', borderRadius: '4px', padding: '4px 8px', width: '100%', overflow: 'hidden' }">
                                    <div class="flex items-center justify-between w-full" style="overflow: hidden;">
                                        <div class="truncate flex-1"
                                             style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{
                                                preset.name
                                            }}
                                        </div>
                                        <button @click.stop="deleteSavedPreset(index)"
                                                class="text-red-500 hover:text-red-700 ml-2 flex-shrink-0">×
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </a-option>
                    </a-select>
                </div>

                <!-- 方向 -->
                <div class="pb-2">
                    <a-select v-model="direction" @change="drawCanvas"
                              class="w-full border border-gray-300 rounded-md shadow-sm" placeholder="选择方向">
                        <a-option value="to right">水平</a-option>
                        <a-option value="to bottom">垂直</a-option>
                        <a-option value="to bottom right">对角线</a-option>
                    </a-select>
                </div>

                <!-- 尺寸 -->
                <div class="pb-2">
                    <h3 class="font-semibold mb-3">导出尺寸</h3>
                    <div class="flex items-center gap-2">
                        <a-input-number v-model="exportWidth" :min="1" :max="10000" placeholder="宽度"
                                        class="flex-1 border border-gray-300 rounded-md shadow-sm"/>
                        <span>x</span>
                        <a-input-number v-model="exportHeight" :min="1" :max="10000" placeholder="高度"
                                        class="flex-1 border border-gray-300 rounded-md shadow-sm"/>
                    </div>
                    <a-select v-model="selectedVideoSize as any" @change="applyVideoSize as any"
                              placeholder="选择视频尺寸"
                              class="w-full border border-gray-300 rounded-md shadow-sm mt-3">
                        <a-option v-for="(size, index) in videoSizes" :key="size.label" :value="index">
                            {{ size.label }} ({{ size.width }}x{{ size.height }})
                        </a-option>
                    </a-select>
                </div>

                <!-- 操作 -->
                <div class="pb-2">
                    <div class="space-y-2">
                        <button @click="copyCSS" class="w-full p-2 bg-blue-500 text-white rounded text-sm">
                            复制CSS
                        </button>
                        <button @click="exportPNG" class="w-full p-2 bg-green-500 text-white rounded text-sm">
                            导出PNG
                        </button>
                        <button @click="savePreset" class="w-full p-2 bg-purple-500 text-white rounded text-sm">
                            保存预设
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 保存预设Modal -->
        <a-modal v-model:visible="saveModalVisible" title="保存预设" @ok="confirmSavePreset"
                 @cancel="saveModalVisible = false" :width="300">
            <div class="mb-4">
                <label class="block text-sm font-medium text-gray-700 mb-2">预设名称</label>
                <a-input v-model="presetName" placeholder="请输入预设名称"/>
            </div>
        </a-modal>
    </div>
</template>
